package Serialization;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.GregorianCalendar;

import Carte.Trajet;
import Carte.Ville;
import Client.Reservation;
import Passager.Passager;
import Serveur.Serveur;
import Services.ServiceChoisis;
import Transports.Avion;
import Transports.Bateau;
import Transports.Bus;
import Transports.Train;
import Transports.Transports;
import Transports.TypeTransport;

public class SerialisationObject extends Serialisation{
	private static final String FICHIER_LISTE_TRANSPORT = "listeTransport.txt2";
	private static final String FICHIER_LISTE_TRAJET = "listeTrajet.txt2";
	private static final String FICHIER_LISTE_RESERVATION = "listeReservation.txt2";
	private static final String FICHIER_LISTE_PASSAGER = "listePassager.txt2";

	private ObjectOutputStream ObjectOutput;
	private ObjectInputStream ObjectInput;
	private ObjectOutputStream ObjectOutput2;
	private ObjectInputStream ObjectInput2;
	private ObjectOutputStream ObjectOutput3;
	private ObjectInputStream ObjectInput3;
	private ObjectOutputStream ObjectOutput4;
	private ObjectInputStream ObjectInput4;

	public SerialisationObject(Serveur serv) {
		super(serv);
		initOutput();
		initInput();
	}

	/**
	 * initialise les ecritures fichiers
	 * 
	 * @param return
	 */
	public void initOutput() {
		FileOutputStream fos;
		try {
			fos = new FileOutputStream(FICHIER_LISTE_TRANSPORT);
			ObjectOutput = new ObjectOutputStream(fos);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("Impossible d'ouvrir le fichier "
					+ FICHIER_LISTE_TRANSPORT);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		FileOutputStream fos2;
		try {
			fos2 = new FileOutputStream(FICHIER_LISTE_TRAJET);
			ObjectOutput2 = new ObjectOutputStream(fos2);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("Impossible d'ouvrir le fichier "
					+ FICHIER_LISTE_TRAJET);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		FileOutputStream fos3;
		try {
			fos3 = new FileOutputStream(FICHIER_LISTE_RESERVATION);
			ObjectOutput3 = new ObjectOutputStream(fos3);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("Impossible d'ouvrir le fichier "
					+ FICHIER_LISTE_RESERVATION);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		FileOutputStream fos4;
		try {
			fos4 = new FileOutputStream(FICHIER_LISTE_PASSAGER);
			ObjectOutput4 = new ObjectOutputStream(fos4);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("Impossible d'ouvrir le fichier "
					+ FICHIER_LISTE_RESERVATION);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void initFichier() {
		File monFichier = new File(FICHIER_LISTE_TRANSPORT);
		if (!monFichier.exists()) {
			try {
				monFichier.createNewFile(); // Cette fonction doit être appelée
				// au sein d'un bloc TRY
			} catch (IOException e) {
				System.out.println("Impossible de créer le fichier");
			}
		}
		File monFichier2 = new File(FICHIER_LISTE_TRAJET);
		if (!monFichier2.exists()) {
			try {
				monFichier2.createNewFile(); // Cette fonction doit être appelée
				// au sein d'un bloc TRY
			} catch (IOException e) {
				System.out.println("Impossible de créer le fichier");
			}
		}
		File monFichier3 = new File(FICHIER_LISTE_RESERVATION);
		if (!monFichier3.exists()) {
			try {
				monFichier3.createNewFile(); // Cette fonction doit être appelée
				// au sein d'un bloc TRY
			} catch (IOException e) {
				System.out.println("Impossible de créer le fichier");
			}
		}
		File monFichier4 = new File(FICHIER_LISTE_PASSAGER);
		if (!monFichier4.exists()) {
			try {
				monFichier4.createNewFile(); // Cette fonction doit être appelée
				// au sein d'un bloc TRY
			} catch (IOException e) {
				System.out.println("Impossible de créer le fichier");
			}
		}
	}

	public void reset() {
		File monFichier = new File(FICHIER_LISTE_TRANSPORT);
		if (monFichier.exists()) {
			monFichier.delete();
		}
		File monFichier2 = new File(FICHIER_LISTE_TRAJET);
		if (monFichier2.exists()) {
			monFichier2.delete();
		}
		File monFichier3 = new File(FICHIER_LISTE_RESERVATION);
		if (!monFichier3.exists()) {
			monFichier3.delete();
		}
		File monFichier4 = new File(FICHIER_LISTE_PASSAGER);
		if (!monFichier4.exists()) {
			monFichier4.delete();
		}
		initFichier();
	}

	/**
	 * initialise les lectures fichiers
	 * 
	 * @param return
	 */
	public void initInput() {
		initFichier();
		FileInputStream fis;
		try {
			fis = new FileInputStream(FICHIER_LISTE_TRANSPORT);
			ObjectInput = new ObjectInputStream(fis);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("Impossible d'ouvrir le fichier "
					+ FICHIER_LISTE_TRANSPORT);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		FileInputStream fis2;
		try {
			fis2 = new FileInputStream(FICHIER_LISTE_TRAJET);
			ObjectInput2 = new ObjectInputStream(fis2);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("Impossible d'ouvrir le fichier "
					+ FICHIER_LISTE_TRAJET);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		FileInputStream fis3;
		try {
			fis3 = new FileInputStream(FICHIER_LISTE_RESERVATION);
			ObjectInput3 = new ObjectInputStream(fis3);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("Impossible d'ouvrir le fichier "
					+ FICHIER_LISTE_RESERVATION);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		FileInputStream fis4;
		try {
			fis4 = new FileInputStream(FICHIER_LISTE_PASSAGER);
			ObjectInput4 = new ObjectInputStream(fis4);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println("Impossible d'ouvrir le fichier "
					+ FICHIER_LISTE_PASSAGER);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * ferme les fichiers et appel les methodes pour sauvegarder les donnees
	 * 
	 * @param ListeTransport
	 * @param ListeTrajet
	 * @param ListeReservation
	 *            return
	 */
	public void closeOutput() {
		try {
			ObjectOutput.close();
			ObjectOutput2.close();
			ObjectOutput3.close();
			ObjectOutput4.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * ferme les fichiers et appel les methodes pour sauvegarder les donnees
	 * 
	 * @param ListeTransport
	 * @param ListeTrajet
	 * @param ListeReservation
	 *            return
	 */
	public void closeInput() {
		try {
			ObjectInput.close();
			ObjectInput2.close();
			ObjectInput3.close();
			ObjectInput4.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * sauvegarde tout les transports/trajets/reservations dans les fichiers
	 * 
	 * @param ListeTransport
	 * @param ListeTrajet
	 * @param ListeReservation
	 * @return
	 */
	public void serializeListe(ArrayList<Transports> ListeTransport,
			ArrayList<Trajet> ListeTrajet,
			ArrayList<Reservation> ListeReservation,
			ArrayList<Passager> ListePassager
	) {
		
		/**
		 * Vider les fichiers
		 */
		reset();
		
		/**
		 * Initiliser la sortie
		 */
		initOutput();

		
		try {
			ObjectOutput.writeObject(serializeListeTransport(ListeTransport));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
//		try {
//			ObjectOutput2.writeObject(serializeListeTrajet(ListeTrajet));
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		try {
//			ObjectOutput3.writeObject(serializeListeReservation(ListeReservation));
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		try {
//			ObjectOutput4.writeObject(serializeListePassager(ListePassager));
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
		
		closeOutput();
	}

	/**
	 * 
	 * @param t
	 * @return
	 */
	private ArrayList<Object> serializeListeTransport(ArrayList<Transports> t){

		ArrayList<Object> obj2 = new ArrayList<Object>();

		for(int i=0; i<t.size(); i++){
			Transports tcourant = t.get(i);
			ArrayList<Object> obj = new ArrayList<Object>();
			obj.add(tcourant.getIdTransport());
			obj.add(tcourant.getCapacite());
			obj.add(tcourant.getPrixBillet());
			obj.add(tcourant.getTypeDuTransport());

			obj2.add(obj);
		}
		return obj2;
	}

	/**
	 * 
	 * @param t
	 * @return
	 */
	private ArrayList<Object> serializeListeTrajet(ArrayList<Trajet> t){
		ArrayList<Object> obj2 = new ArrayList<Object>();

		for(int i=0; i<t.size(); i++){
			Trajet tcourant = t.get(i);
			ArrayList<Object> obj = new ArrayList<Object>();
			obj.add(tcourant.getIDTrajet());
			obj.add(tcourant.getVilleDepart());
			obj.add(tcourant.getVilleArrive());
			obj.add(tcourant.getDatedepart());
			obj.add(tcourant.getDatearrive());
			obj.add(tcourant.getPlaceOcupper());
			obj.add(tcourant.getIdTransport());
			obj.add(tcourant.getDistance());

			obj2.add(obj);
		}

		return obj2;
	}

	/**
	 * 
	 * @param r
	 * @return
	 */
	private ArrayList<Object> serializeListeReservation(ArrayList<Reservation> r){
		ArrayList<Object> obj2 = new ArrayList<Object>();

		for(int i=0; i<r.size(); i++){
			ArrayList<Object> obj = new ArrayList<Object>();
			Reservation rcourante = r.get(i); 
			obj.add(rcourante.getIdReservation());
			obj.add(rcourante.getIdTrajet());
			obj.add(rcourante.getDate());
			obj.add(rcourante.getNbPersonne());
			obj.add(rcourante.getListePassager());
			obj.add(rcourante.getListeServiceChoisi());

			obj2.add(obj);
		}

		return obj2;
	}

	/**
	 * 
	 * @param p
	 * @return
	 */
	private ArrayList<Object> serializeListePassager(ArrayList<Passager> p){
		ArrayList<Object> obj2 = new ArrayList<Object>();

		for(int i=0; i<p.size(); i++){
			ArrayList<Object> obj = new ArrayList<Object>();
			Passager pcourant = p.get(i);
			obj.add(pcourant.getIdPassager());
			obj.add(pcourant.getNom());
			obj.add(pcourant.getPrenom());

			obj2.add(obj);
		}

		return obj2;
	}

	@Override
	public ArrayList<Transports> fillOutListeTransport() {
		
		ArrayList<Object> ListeObj = new ArrayList<Object>();
		ArrayList<Transports> ListeTransport = new ArrayList<Transports>();
		try {
			if (ObjectInput.available() >= 0) {
				try {
					ListeObj = (ArrayList<Object>) ObjectInput.readObject();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					//e.printStackTrace();
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					//e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}

		for(int i=0; i<ListeObj.size(); i++){
			ArrayList<Object> objCourant = (ArrayList<Object>) ListeObj.get(i);

			Transports temp = null;
			TypeTransport type = (TypeTransport) objCourant.get(3);
			switch(type){
			case AVION:
				temp = new Avion(serv, (Integer)objCourant.get(0), (Double)objCourant.get(2), (Integer)objCourant.get(1));
				break;
			case BATEAU:
				temp = new Bus(serv, (Integer)objCourant.get(0), (Double)objCourant.get(2), (Integer)objCourant.get(1));
				break;
			case BUS:
				temp = new Train(serv, (Integer)objCourant.get(0), (Double)objCourant.get(2), (Integer)objCourant.get(1));
				break;
			case TRAIN:
				temp = new Bateau(serv, (Integer)objCourant.get(0), (Double)objCourant.get(2), (Integer)objCourant.get(1));
				break;
			}
			ListeTransport.add(temp);			
		}

		closeInput();
		return ListeTransport;
	}

	@Override
	public ArrayList<Passager> fillOutListePassager() {		
		ArrayList<Object> ListeObj = new ArrayList<Object>();
		ArrayList<Passager> ListePassager= new ArrayList<Passager>();
		try {
			if (ObjectInput4.available() >= 0) {
				try {
					ListeObj = (ArrayList<Object>) ObjectInput4.readObject();
					
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		for(int i=0; i<ListeObj.size(); i++){
			ArrayList<Object> objCourant = (ArrayList<Object>) ListeObj.get(i);
			Passager temp = new Passager(serv, (Integer)objCourant.get(0), objCourant.get(1).toString(), objCourant.get(2).toString());
			ListePassager.add(temp);
		}
		return ListePassager;
	}

	@Override
	public ArrayList<Reservation> fillOutListeReservation() {
		ArrayList<Object> ListeObj = new ArrayList<Object>();
		ArrayList<Reservation> ListeReservation = new ArrayList<Reservation>();
		try {
			if (ObjectInput3.available() >= 0) {
				try {
					ListeObj = (ArrayList<Object>) ObjectInput3.readObject();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					//e.printStackTrace();
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					//e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
		
		for(int i=0; i<ListeObj.size(); i++){
			ArrayList<Object> objCourant = (ArrayList<Object>) ListeObj.get(i);

			for(int j=0; j<objCourant.size(); j++){

				Reservation temp = new Reservation(serv, (Integer)objCourant.get(1), (ArrayList<Integer>)objCourant.get(4), (ArrayList<ServiceChoisis>)objCourant.get(5), (Integer)objCourant.get(0), (GregorianCalendar)objCourant.get(2));
				temp.setReserver(true);
				ListeReservation.add(temp);
			}
		}
	
		return ListeReservation;
	}

	@Override
	public ArrayList<Trajet> fillOutListeTrajet() {
		ArrayList<Object> ListeObj = new ArrayList<Object>();
		ArrayList<Trajet> ListeTrajet = new ArrayList<Trajet>();
		try {
			if (ObjectInput2.available() >= 0) {
				try {
					ListeObj = (ArrayList<Object>) ObjectInput2.readObject();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					//e.printStackTrace();
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					//e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}

		for(int i=0; i<ListeObj.size(); i++){
			ArrayList<Object> objCourant = (ArrayList<Object>) ListeObj.get(i);

			for(int j=0; j<objCourant.size(); j++){

				Trajet temp = new Trajet(serv, (Ville)objCourant.get(1),(Ville)objCourant.get(2), (GregorianCalendar)objCourant.get(3), (GregorianCalendar)objCourant.get(4), (Integer)objCourant.get(6), (Integer)objCourant.get(7), (Integer)objCourant.get(0));
				temp.setPlaceOcupper((Integer)objCourant.get(5));
				ListeTrajet.add(temp);
			}
		}
		return ListeTrajet;
	}
}
